package lang;

import org.junit.Test;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.*;

/**
 * @author Khai Loon
 * @date 2018/6/6
 */
public class ThreadLocal_ {

    private static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();


    @Test
    public void test4() throws InterruptedException {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

        threadLocal.set(1);
        Thread newThread = new Thread(() -> {

            try {
                Thread.sleep(2L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            executor.execute(() -> {
                System.out.println("get" + threadLocal.get());
            });

        });


        newThread.start();


        Thread.currentThread().join();
    }


    @Test
    public void hash() {
        int t = 0x61c88647;
        int count = 0;

        TreeSet<Integer> set = new TreeSet<>();
        for (int i = 0; i < 16; i++) {
            count += t;
            set.add(count & (16 - 1));
        }

        System.out.println(set);//刚好每个元素都用到了，完美分配
        System.out.println(set.size() == 16);
    }

    /**
     * 强 内存不足不会回收  Object obj =new Object();
     * 软 内存不足时才回收  SoftReference<String> sr = new SoftReference<String>(new String("hello"));
     * 弱 weak
     * 虚
     */
    @Test
    public void ref() {
        String obj = "xx";
        PhantomReference<String> pf = new PhantomReference<>(obj, new ReferenceQueue<>());
        //obj=null;
        System.out.println(pf.get());//永远返回null
    }


    public static class A {
    }

    //最简单模拟弱应用
    @Test
    public void test2() {
        A a = new A();
        WeakReference<A> weakA = new WeakReference<>(a);
        a = null;      //可以控制变为空   2个条件回收 1:没有任何引用指向它 2:GC运行
        System.gc();
        System.out.println(weakA.get());//返回空 牛逼不 哈哈哈哈
    }

    //测试ThreadLocal 弱引用 什么时候回收
    @Test
    public void test3() throws NoSuchFieldException, IllegalAccessException {
        ThreadLocal<String> local = new ThreadLocal<>();
        local.set("xxx");

        local = null;
        System.gc();

        Thread thread = Thread.currentThread();
        Field field = Thread.class.getDeclaredField("threadLocals");
        field.setAccessible(true);
        Object map = field.get(thread); //对象变为空

        //总结  ThreadLocal 不设置 null 的时候 永远不会 执行弱引用 清理,referent 变成空
    }

    // WeakHashMap 弱应用清除缓存
    static WeakHashMap<Object, Object> weakMap = new WeakHashMap<>();

    @Test
    public void test5() throws NoSuchFieldException, IllegalAccessException {
        test6();
        System.gc();
        System.out.println(weakMap.toString());


        Field table = WeakHashMap.class.getDeclaredField("table");
        table.setAccessible(true);
        Object o =  table.get(weakMap);

    }

    public void test6() {
        weakMap.put(new Object(), "bbbb");
    }


}
